home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / perl / msds-prl / ptchds19.zoo / argv_asm next >
Text File  |  1992-02-23  |  10KB  |  365 lines

  1. MS-DOS patches to perl.
  2. Apply this patch to the standard perl source, version 4, patch level 19,
  3. using "patch -p."  Do this in the root directory of the perl source
  4. distribution.
  5.  
  6. You can cat all these patches together and pipe the output to patch -p.
  7.  
  8. Len Reed
  9. Holos Software, Inc.
  10. ..!gatech!holos0!lbr
  11. holos0!lbr@gatech.edu
  12. --------------------------------------
  13. *** msdos/argv.asm.old    Sun Feb 23 08:48:16 1992
  14. --- msdos/argv.asm    Thu Nov 14 08:56:28 1991
  15. ***************
  16. *** 0 ****
  17. --- 1,347 ----
  18. + ; Invoke MKS argument handler.  If succcesful, return.
  19. + ; If unsuccessful, call MS-DOS __argv to process the command line.
  20. + ; Called by MS-DOS C startup code (crt0.obj in the C library).
  21. + ; This code used detailed knowledge of how the Microsoft C 6.0 startup
  22. + ; code works.  That source is distributed with the compiler, in
  23. + ; lib/startup and lib/startup/dos, so we're not talking about a terrible
  24. + ; guessing game here.
  25. + ; This code contains no MKS or Microsoft copyrighted code.
  26. + ; This program is free software; you can redistribute it and/or
  27. + ; modify it under the terms of the GNU General Public License
  28. + ; (version 1), as published by the Free Software Foundation, and
  29. + ; found in the file 'LICENSE' included with this distribution.
  30. + ; This program is distributed in the hope that it will be useful,
  31. + ; but WITHOUT ANY WARRANTY; without even the implied warrant of
  32. + ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33. + ; GNU General Public License for more details.
  34. + ; You must assemble this file with masm flag
  35. + ;    -dmmodel where model is one of {small, compact, medium, large}
  36. + ;
  37. + ifdef msmall
  38. +         .model    small
  39. +   ARG    equ    4
  40. + endif
  41. + ifdef mcompact
  42. +     .model  compact
  43. +   ARG    equ    4
  44. + endif
  45. + ifdef mmedium
  46. +     .model    medium
  47. +   ARG    equ    6
  48. + endif
  49. + ifdef mlarge
  50. +     .model    large
  51. +   ARG    equ    6
  52. + endif
  53. + ;-------------------------
  54. + ; The Microsoft startup code calls __setenvp and then __setargv.  Each of
  55. + ; these can return a changed stack pointer.  The routines set ___argv,
  56. + ; ___argc, and environ.
  57. + .DATA
  58. + If @codesize
  59. + return_adr dd ?
  60. + Else
  61. + return_adr dw ?
  62. + Endif
  63. + extrn __psp:word    ; our PSP segment, set by startup before __setenvp
  64. + extrn ___argc:word    ; pointer to argv[], used by startup in calling main
  65. + extrn _environ:word    ; ptr to environment ptrs, used by startup calling main
  66. + extrn STKHQQ:word    ; top of stack, defined by Microsoft C startup
  67. + extrn __osversion:word    ; MS-DOS version
  68. + gseg    dw    ?    ; segment of buffer passed to MKS glob
  69. +     Public _com_slashc
  70. + _com_slashc db    '/c', 0    ; default switch for command.com
  71. + .CODE
  72. + extrn ___setargv:proc    ; Microsoft globber, in C library
  73. + extrn __amsg_exit:proc    ; Microsoft stack overflow death, in C library
  74. + extrn _mks_init:proc    ; C code to do MKS argument analysis
  75. + extrn _mks_globber:proc    ; C code to run MKS glob.exe
  76. + DONT_USE equ 400h    ; stack space that must be left over after
  77. +             ; processing arguments
  78. + ; Define MIN_DOS_VER to be minimum version of DOS to support times 100,
  79. + ; using the -D assembler option.  If undefined, assume 2.0.
  80. + Ifndef MIN_DOS_VER
  81. +  MIN_DOS_VER Equ 200    ; have to at least have handle I/O, in ver 2.00
  82. + Endif
  83. + If MIN_DOS_VER lt 300
  84. + exec_ss    dw    ?    ; needed to support DOS 2.xx exec system call
  85. + exec_sp    dw    ?
  86. + Endif
  87. +     Public __setenvp
  88. + __setenvp Proc
  89. +     pop ax
  90. +     mov word ptr return_adr,ax
  91. + If @codesize
  92. +     pop ax
  93. +     mov word ptr return_adr + 2,ax
  94. + Endif
  95. +     mov ax,3000h    ; get MS-DOS version.
  96. +     int 21h
  97. +     mov __osversion,ax    ; Microsoft code we're replacing does this, too.
  98. +     mov dx,ax
  99. +     xchg dl,dh        ; version from DOS is in wrong byte order!
  100. +     cmp dx,MIN_DOS_VER    ; Approprite DOS version
  101. +     jae ver_okay
  102. +     mov bx,4        ; error message number
  103. +     jmp version_death
  104. + ver_okay:
  105. +     cmp al,4        ; if version 4 or beyond ignore switch char
  106. +     jae ver_4
  107. +     mov ax,3700h    ; get switch char, usually / or -
  108. +     int 21h
  109. +     mov _com_slashc,dl    ; set the switch character
  110. + ver_4:
  111. +     mov ax,STKHQQ    ; min SP: below this is stack overflow
  112. +     add ax,DONT_USE    ; retain some space, AX will be mks_init's SP
  113. +     cmp sp,ax        ; make sure that DONT_USE doesn't exhaust the stack
  114. +     jb too_little    ; sorry--expand the stack
  115. +     mov dx,sp
  116. +     sub dx,ax        ; DX has amount of space mks_init can play with
  117. +     mov sp,ax        ; allocate that space for mks_init
  118. +     push dx        ; tell C program how much space he gets
  119. +     call _mks_init    ; parse envp and args, return stack space used
  120. +                 ; return -1 for insufficient stack space
  121. +     pop dx        ; total that was available
  122. +     cmp ax,0FFFFh    ; was there enough space?
  123. +     je not_enough
  124. +     sub dx,ax        ; subtract off amount actually used
  125. +     add sp,dx        ; reduce stack by amount not used
  126. +     cmp ___argc,0    ; did we find the MKS arguments?
  127. +     jnz done_with_args
  128. +     sub sp,dx        ; reallocate the remaining space
  129. +     push dx        ; tell mks_globber how big it is
  130. +     call _mks_globber    ; try running MKS glob program
  131. +     pop dx        ; total that was available
  132. +     cmp ax,0FFFFh    ; was there enough space?
  133. +     je not_enough
  134. +     sub dx,ax        ; subtract off amount actually used
  135. +     add sp,dx        ; reduce stack by amount not used
  136. +     mov ax,gseg
  137. +     or ax,ax
  138. +     jz gspace_freed
  139. +     mov es,ax
  140. +     mov ah,49h        ; free the memory block used by glob
  141. +     int 21h
  142. + gspace_freed:
  143. +     cmp ___argc,0    ; did MKS glob program succeed?
  144. +     jnz done_with_args
  145. + ; Last chance, and it's a poor third choice, is to let Microsoft's globber run
  146. + ; It won't handle single quotes and thinks *.* matches abc and that * doesn't
  147. + ; match "abc.c".  It will also change the file names to upper case.  If
  148. + ; someone doesn't like that he can write a globber.
  149. +     call ___setargv
  150. + done_with_args:
  151. +     jmp return_adr
  152. + not_enough:
  153. +     add sp,dx        ; recover all the space that was allocated
  154. + too_little:
  155. +     xor ax,ax        ; message zero
  156. +     jmp    __amsg_exit    ; stack overflow message and die
  157. + __setenvp  Endp
  158. + ; Resolve Microsoft C's need for the following routine
  159. +     Public __setargv
  160. + __setargv  Proc
  161. +   ret            ; all was done by _setenvp
  162. + __setargv Endp
  163. + .DATA
  164. + fcb_one    db    0, 12 dup(' ')
  165. + fcb_two    db    0, 12 dup(' ')
  166. + gtt    db    1, ' ', '\r', '\n'    ; glob's tail is null
  167. + genv    dw    ?    ; segment of glob's environment
  168. + gtail    dd    gtt    ; pointer to glob's command tail
  169. + gfcb1    dd    fcb_one    ; first FCB
  170. + gfcb2    dd    fcb_two    ; second FCB
  171. + .CODE
  172. + ; Subroutine to get space for running MKS glob program.
  173. + ; Can't be using malloc() this early, so we call DOS directly.
  174. + ; Return a far pointer to the allocated 8K space, 0 for failure.
  175. +     Public _get_glob_space
  176. + _get_glob_space Proc
  177. +     mov ah,48h        ; MS-DOS allocate memory call
  178. +     mov bx,201h        ; 8 Kilobytes worth of paragraphs plus one paragraph
  179. +                 ; the extra paragraph is used for glob's environment
  180. +     int 21h
  181. +     jnc got_it
  182. +     sub ax,ax        ; not enough memory
  183. +     mov dx,ax
  184. +     ret
  185. + got_it:
  186. +     mov gseg,ax        ; save segment address
  187. +     mov dx,ax        ; return segment address
  188. +     sub ax,ax        ; offset is always zero
  189. +     ret
  190. + _get_glob_space Endp
  191. + ; Run the MKS glob program.
  192. + ; Arguments are standard pointer to the glob program name and far
  193. + ; pointer to the glob buffer.
  194. +     Public _spawn_mks_glob
  195. + one_dig Proc Near    ; convert to ascii and store 1 hex digit
  196. +     mov ax,dx
  197. +     and ax,0fh
  198. +     add ax,30h
  199. +     cmp ax,39h
  200. +     jbe one_dec
  201. +     add ax,7        ; change 3A to 41 ('A'), 3B to 'B' etc.
  202. + one_dec:
  203. +     mov es:[bx],al
  204. +     dec bx
  205. +     shr dx,cl
  206. +     ret
  207. + one_dig Endp
  208. + _spawn_mks_glob Proc
  209. +     push bp
  210. +     mov bp,sp
  211. +     push si
  212. +     push di
  213. +     mov ax,gseg        ; segment of glob buffer
  214. +     mov dx,ax        ; save for making ascii string
  215. +     add ax,200h        ; segment of where we'll put the environment
  216. +     mov genv,ax
  217. +     mov es,ax
  218. +     mov cx,4
  219. +     mov bx,3
  220. +     call one_dig
  221. +     call one_dig
  222. +     call one_dig
  223. +     call one_dig
  224. +     mov es:word ptr [4],3030h    ; we know glob buffer starts at para address
  225. +     mov es:word ptr [6],3030h
  226. +     mov es:byte ptr [8],0    ; terminate the string
  227. +     mov ax,@data        ; set ES:BX pointing to spawn parameter block
  228. +     mov es,ax
  229. +     lea bx,genv
  230. + If @datasize
  231. +     mov ds,[bp+ARG+2]        ; segment of program name
  232. + Endif
  233. +     mov dx,[bp+ARG]        ; offset of program name
  234. + If MIN_DOS_VER lt 300
  235. +     ; DOS 2.x is brain-damaged and will clobber all but CS:IP
  236. +     push ds
  237. +     mov exec_ss,ss
  238. +     mov exec_sp,sp
  239. + Endif
  240. +     mov ax,4b00h        ; spawn the glob program
  241. +     int 21h            ; we're assuming DOS 3.0+; 2.x trashes regs
  242. + If MIN_DOS_VER lt 300
  243. +     mov ss,exec_ss        ; will delay interrupts til after next instr
  244. +     mov sp,exec_sp        ; movs and pops don't change CF
  245. +     pop ds
  246. + Endif
  247. +     mov ah,0ffh            ; assume failure: note doesn't affect carry
  248. +     jc spawn_done        ; problem: return MS-DOS error code
  249. +     mov ah,4dh            ; get return code of glob
  250. +     int 21h
  251. + spawn_done:    ; return code in AX, if spawn failed, AH == 0FFh
  252. +     mov cx,ss
  253. +     mov ds,cx
  254. +     pop di
  255. +     pop si
  256. +     pop bp
  257. +     ret
  258. + _spawn_mks_glob Endp
  259. + ; Catastophe calling glob.exe.  Print message and die
  260. + .DATA
  261. + gmsg0    db 'glob: not found', 13, 10
  262. + gmsg1    db 'glob: insufficient space', 13, 10
  263. + gmsg2    db 'glob: unknown problem', 13, 10
  264. + gmsg3    db 'glob: arg list too long', 13, 10
  265. + gmsg4    db 'DOS '
  266. +     db (MIN_DOS_VER shr 8) or 30h    ; ascii major
  267. +     db '.'
  268. +     db ((MIN_DOS_VER and 0f0h) shr 4) or 30h ; ascii minor (tens)
  269. +     db (MIN_DOS_VER and 0fh) or 30h         ; ascii minor (units)
  270. +     db ' or better required', 13, 10
  271. + gmsg    dw gmsg0, gmsg1, gmsg2, gmsg3, gmsg4
  272. +     dw gmsg
  273. + .CODE
  274. +     Public _glob_problem
  275. + _glob_problem Proc
  276. +     push bp
  277. +     mov bp,sp
  278. +     mov bx,[bp+ARG]    ; get message index
  279. + version_death:
  280. +     shl bx,1        ; convert to word index
  281. +     mov dx,[bx].gmsg    ; get offset of the message
  282. +     mov cx,[bx+2].gmsg    ; get offset of next message
  283. +     sub cx,dx        ; bytes in between
  284. +     mov bx,2        ; write to stderr
  285. +     mov ah,40h
  286. +     int 21h
  287. +     mov ax,4c01h    ; terminte with return code 1
  288. +     int 21h
  289. +     ; no return
  290. + _glob_problem Endp
  291. + End
  292.